package com.youkeyi.ddy.cloud.basic.pub.menu.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youkeyi.ddy.cloud.basic.pub.mapping.entity.SysMapping;
import com.youkeyi.ddy.cloud.basic.pub.mapping.param.BusinessDeleteParam;
import com.youkeyi.ddy.cloud.basic.pub.mapping.param.BusinessQueryParam;
import com.youkeyi.ddy.cloud.basic.pub.mapping.service.SysMappingService;
import com.youkeyi.ddy.cloud.basic.pub.menu.entity.SysMenu;
import com.youkeyi.ddy.cloud.basic.pub.menu.service.SysMenuService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.PublicMenuCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.dto.PublicMenuListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.dto.PublicMenuListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuCreateCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuDeleteCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyCloudBasicPublicConstant;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.response.ResponseContent;
import com.youkeyi.ddy.cloud.common.utils.SimpleUUidUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表
 前端控制器
 * </p>
 *
 * @author xiawang.liu
 * @since 2024-02-21
 */
@Service
public class SysMenuController implements PublicMenuCloudService {

    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysMappingService sysMappingService;

    @Override
    public PublicMenuListCloudDto query(PublicMenuQueryCloudParam param) {
        PublicMenuListCloudDto dto = new PublicMenuListCloudDto();
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        if (CollectionUtils.isNotEmpty(param.getMenuPrimaryKeys())) {
            param.getMenuPrimaryKeys().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getCodes())) {
            param.getCodes().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getNames())) {
            param.getNames().removeAll(Collections.singleton(null));
        }
        if (CollectionUtils.isNotEmpty(param.getParentKeys())) {
            param.getParentKeys().removeAll(Collections.singleton(null));
        }

        QueryWrapper<SysMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .in(CollectionUtils.isNotEmpty(param.getMenuPrimaryKeys()), SysMenu::getPrimaryKey, param.getMenuPrimaryKeys())
                .in(CollectionUtils.isNotEmpty(param.getNames()), SysMenu::getName, param.getNames())
                .like(StringUtils.isNotBlank(param.getNameFuzzy()), SysMenu::getName, param.getNameFuzzy())
                .in(CollectionUtils.isNotEmpty(param.getCodes()), SysMenu::getCode, param.getCodes())
                .in(CollectionUtils.isNotEmpty(param.getParentKeys()), SysMenu::getParentKey, param.getParentKeys())
                .like(StringUtils.isNotBlank(param.getPath()), SysMenu::getPath, param.getPath())
                .ne(SysMenu::getIsDeleted, YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value())
        ;

        Page<SysMenu> page = new Page<>();
        if (null != param.getCurrentPage() && null != param.getPageSize()) {
            page.setCurrent(param.getCurrentPage());
            page.setSize(param.getPageSize());
        } else {
            page.setCurrent(1);
            page.setSize(99999999);
        }
        Page<SysMenu> menuList = sysMenuService.page(page, wrapper);
        if (CollectionUtils.isNotEmpty(menuList.getRecords())) {
            dto.setTotal(menuList.getTotal());

            // 查询映射数据
            BusinessQueryParam queryMappingParam = new BusinessQueryParam();
            queryMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_MENU_AUTH.value());
            queryMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
            queryMappingParam.setKeys(menuList.getRecords().stream().map(SysMenu::getPrimaryKey).collect(Collectors.toList()));
            Map<String, List<String>> serverKeysMap = new HashMap<>();
            List<SysMapping> sysMappings = sysMappingService.businessQuery(queryMappingParam);
            if (CollectionUtils.isNotEmpty(sysMappings)) {
                sysMappings.forEach(mapping -> {
                    if (!serverKeysMap.containsKey(mapping.getSourceKey())) {
                        serverKeysMap.put(mapping.getSourceKey(), new ArrayList<>());
                    }
                    serverKeysMap.get(mapping.getSourceKey()).add(mapping.getTargetKey());
                });
            }


            List<PublicMenuListItemCloudDto> items = new ArrayList<>();
            menuList.getRecords().forEach(menu -> {
                PublicMenuListItemCloudDto item = new PublicMenuListItemCloudDto();
                item.setMenuPrimaryKey(menu.getPrimaryKey());
                item.setName(menu.getName());
                item.setCode(menu.getCode());
                item.setUrl(menu.getUrl());
                item.setIcon(menu.getIcon());
                item.setRemark(menu.getRemark());
                item.setSort(menu.getSort());
                item.setIsHidden(menu.getIsHidden());
                item.setIsDisabled(menu.getIsDisabled());
                item.setParentKey(menu.getParentKey());
                item.setPath(menu.getPath());
                item.setIsDeleted(menu.getIsDeleted());
                item.setIsDeletedName(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO.getName(item.getIsDeleted()));
                item.setCreateTime(menu.getCreateTime() != null ? menu.getCreateTime().getTime() : null);
                item.setCreateUserKey(menu.getCreateUserKey());
                item.setCreateUserName(menu.getCreateUserName());
                item.setUpdateTime(menu.getUpdateTime() != null ? menu.getUpdateTime().getTime() : null);
                item.setUpdateUserKey(menu.getUpdateUserKey());
                item.setUpdateUserName(menu.getUpdateUserName());
                item.setAuthKeys(serverKeysMap.get(menu.getPrimaryKey()));
                items.add(item);
            });
            dto.setRows(items);
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public ResponseContent create(PublicMenuCreateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getUrl())
                || StringUtils.isBlank(param.getName()) || StringUtils.isBlank(param.getCode())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }
        SysMenu menu = new SysMenu();
        menu.setPrimaryKey(SimpleUUidUtils.getUuid());
        menu.setName(param.getName());
        menu.setCode(StringUtils.isNotBlank(param.getCode()) ? param.getCode() : String.format("MENU-%s", System.currentTimeMillis()));
        menu.setUrl(param.getUrl());
        menu.setIcon(param.getIcon());
        menu.setRemark(param.getRemark());
        menu.setSort(param.getSort());
        menu.setIsHidden(param.getIsHidden());
        menu.setIsDisabled(param.getIsDisabled());
        menu.setIsDeleted(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_NO.value());
        menu.setCreateUserKey(param.getCreateUserKey());
        menu.setCreateUserName(param.getCreateUserName());
        menu.setCreateTime(new Date());
        // 构造父级数据
        menu.setParentKey("");
        menu.setPath(String.format("|%s|", menu.getPrimaryKey()));
        if (StringUtils.isNotBlank(param.getParentKey())) {
            QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysMenu::getPrimaryKey, param.getParentKey());
            SysMenu parentMenu = sysMenuService.getOne(queryWrapper);
            if (null != parentMenu && StringUtils.isNotBlank(parentMenu.getPrimaryKey())) {
                menu.setParentKey(parentMenu.getPrimaryKey());
                menu.setPath(String.format("%s|", parentMenu.getPath()));
            }
        }

        boolean save = sysMenuService.save(menu);
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
            return rc;
        }

        // 服务数据录入
        if (CollectionUtils.isNotEmpty(param.getAuthKeys())) {
            List<SysMapping> serverCreateParams = new ArrayList<>();
            param.getAuthKeys().forEach(authPrimaryKey -> {
                SysMapping serverMapping = new SysMapping();
                serverMapping.setPrimaryKey(SimpleUUidUtils.getUuid());
                serverMapping.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_MENU_AUTH.value());
                serverMapping.setSourceKey(menu.getPrimaryKey());
                serverMapping.setTargetKey(authPrimaryKey);
                serverMapping.setCreateUserKey(param.getCreateUserKey());
                serverMapping.setCreateUserName(param.getCreateUserName());
                serverCreateParams.add(serverMapping);
            });
            sysMappingService.businessCreate(serverCreateParams);
        }

        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        rc.setKey(menu.getPrimaryKey());
        return rc;
    }

    @Override
    public ResponseContent update(PublicMenuUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || StringUtils.isBlank(param.getMenuPrimaryKey())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }


        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysMenu::getPrimaryKey, param.getMenuPrimaryKey());
        SysMenu myselfMenu = sysMenuService.getOne(queryWrapper);
        if (null == myselfMenu || StringUtils.isBlank(myselfMenu.getPrimaryKey())) {
            rc.setErrorMessage(ResponseCodeEnum.UNKNOWN_ERROR.getMessage());
            return rc;
        }


        UpdateWrapper<SysMenu> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .eq(SysMenu::getPrimaryKey, param.getMenuPrimaryKey());
        SysMenu menu = new SysMenu();
        menu.setPrimaryKey(param.getMenuPrimaryKey());
        menu.setName(param.getName());
        menu.setCode(param.getCode());
        menu.setUrl(param.getUrl());
        menu.setIcon(param.getIcon());
        menu.setRemark(param.getRemark());
        menu.setSort(param.getSort());
        menu.setIsHidden(param.getIsHidden());
        menu.setIsDisabled(param.getIsDisabled());
        menu.setUpdateUserKey(param.getUpdateUserKey());
        menu.setUpdateUserName(param.getUpdateUserName());
        menu.setUpdateTime(new Date());
        if (!myselfMenu.getParentKey().equals(param.getParentKey())) {
            // 构造父级数据
            menu.setParentKey("");
            menu.setPath(String.format("|%s|", menu.getPrimaryKey()));
            if (StringUtils.isNotBlank(param.getParentKey())) {
                QueryWrapper<SysMenu> queryParentWrapper = new QueryWrapper<>();
                queryParentWrapper.lambda().eq(SysMenu::getPrimaryKey, param.getParentKey());
                SysMenu parentMenu = sysMenuService.getOne(queryParentWrapper);
                if (null != parentMenu && StringUtils.isNotBlank(parentMenu.getPrimaryKey())) {
                    menu.setParentKey(parentMenu.getPrimaryKey());
                    menu.setPath(String.format("%s|", parentMenu.getPath()));
                }
            }
        }

        boolean save = sysMenuService.update(menu, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
            return rc;
        }

        // 删除映射数据
        BusinessDeleteParam deleteMappingParam = new BusinessDeleteParam();
        deleteMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_MENU_AUTH.value());
        deleteMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        deleteMappingParam.setKeys(Collections.singletonList(param.getMenuPrimaryKey()));
        sysMappingService.businessDelete(deleteMappingParam);
        // 重新加入映射数据
        if (CollectionUtils.isNotEmpty(param.getAuthKeys())) {
            List<SysMapping> serverCreateParams = new ArrayList<>();
            param.getAuthKeys().forEach(authPrimaryKey -> {
                SysMapping serverMapping = new SysMapping();
                serverMapping.setPrimaryKey(SimpleUUidUtils.getUuid());
                serverMapping.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_MENU_AUTH.value());
                serverMapping.setSourceKey(menu.getPrimaryKey());
                serverMapping.setTargetKey(authPrimaryKey);
                serverMapping.setCreateUserKey(param.getUpdateUserKey());
                serverMapping.setCreateUserName(param.getUpdateUserName());
                serverCreateParams.add(serverMapping);
            });
            sysMappingService.businessCreate(serverCreateParams);
        }
        return rc;
    }

    @Override
    public ResponseContent delete(PublicMenuDeleteCloudParam param) {
        ResponseContent rc = new ResponseContent();
        if (null == param || CollectionUtils.isEmpty(param.getMenuPrimaryKeys())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }
        UpdateWrapper<SysMenu> wrapper = new UpdateWrapper<>();
        wrapper.lambda()
                .in(SysMenu::getPrimaryKey, param.getMenuPrimaryKeys());

        SysMenu menu = new SysMenu();
        menu.setIsDeleted(YoukeyiDdyCloudBasicPublicConstant.SYSTEM_YES_OR_NO_YES.value());
        menu.setUpdateUserKey(param.getUpdateUserKey());
        menu.setUpdateUserName(param.getUpdateUserName());
        menu.setUpdateTime(new Date());
        boolean save = sysMenuService.update(menu, wrapper);
        rc.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        if (!save) {
            rc.setErrorMessage(ResponseCodeEnum.FAIL.getMessage());
        }

        // 删除映射数据
        BusinessDeleteParam deleteMappingParam = new BusinessDeleteParam();
        deleteMappingParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_MENU_AUTH.value());
        deleteMappingParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        deleteMappingParam.setKeys(param.getMenuPrimaryKeys());
        sysMappingService.businessDelete(deleteMappingParam);
        return rc;
    }
}
